package com.fx.zmlzml.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fx.zmlzml.entity.SysUser;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;

/**
 * 系统用户Mapper接口
 * 继承MyBatis-Plus BaseMapper，获得基础CRUD能力
 * @author yourname
 * @since 2025-11-03
 */
@Mapper // Spring注解，标识这是一个MyBatis Mapper接口
public interface SysUserMapper extends BaseMapper<SysUser> {

    /**
     * 根据用户名查询用户
     * 作用：登录时验证用户名是否存在
     * 说明：MyBatis-Plus内置方法selectOne()可替代，但此方法更直观
     * @param username 用户名
     * @return SysUser对象，不存在返回null
     */
    SysUser selectByUsername(@Param("username") String username);

    /**
     * 根据邮箱查询用户
     * 作用：找回密码、邮箱激活等功能
     * @param email 邮箱地址
     * @return SysUser对象，不存在返回null
     */
    SysUser selectByEmail(@Param("email") String email);

    /**
     * 根据手机号查询用户
     * 作用：短信登录、手机绑定等功能
     * @param phone 手机号码
     * @return SysUser对象，不存在返回null
     */
    SysUser selectByPhone(@Param("phone") String phone);

    /**
     * 根据用户名或邮箱查询用户
     * 作用：登录时支持用户名/邮箱两种方式
     * @param usernameOrEmail 用户名或邮箱
     * @return SysUser对象，不存在返回null
     */
    SysUser selectByUsernameOrEmail(@Param("usernameOrEmail") String usernameOrEmail);

    /**
     * 更新最后登录信息
     * 作用：用户成功登录后更新登录时间和IP
     * 说明：使用MyBatis-Plus的update()方法，避免全字段更新
     * @param userId 用户ID
     * @param lastLoginIp 最后登录IP
     * @param lastLoginTime 最后登录时间
     * @return 影响行数
     */
    int updateLastLoginInfo(
            @Param("userId") Long userId,
            @Param("lastLoginIp") String lastLoginIp,
            @Param("lastLoginTime") java.time.LocalDateTime lastLoginTime
    );

    /**
     * 增加登录失败次数
     * 作用：密码错误时记录失败次数，用于账户锁定
     * 说明：原子操作，避免并发问题
     * @param userId 用户ID
     * @return 影响行数
     */
    int incrementFailedLoginCount(@Param("userId") Long userId);

    /**
     * 重置登录失败次数
     * 作用：成功登录后重置失败计数
     * @param userId 用户ID
     * @return 影响行数
     */
    int resetFailedLoginCount(@Param("userId") Long userId);

    /**
     * 锁定用户账户
     * 作用：达到失败次数阈值后锁定账户
     * @param userId 用户ID
     * @param lockTime 锁定时间
     * @return 影响行数
     */
    int lockUserAccount(
            @Param("userId") Long userId,
            @Param("lockTime") java.time.LocalDateTime lockTime
    );

    /**
     * 按状态统计用户数量
     * 作用：后台管理统计
     * @param status 账户状态（0-禁用, 1-正常）
     * @return 用户数量
     */
    Integer countByStatus(@Param("status") Byte status);

    /**
     * 查询最近活跃用户
     * 作用：后台管理展示
     * @param limit 查询数量
     * @return 用户列表
     */
    List<SysUser> selectRecentActiveUsers(@Param("limit") int limit);
}